/**
 * 时间处理工具函数
 */

/**
 * 日期格式类型常量
 * 提供常用的预定义日期格式类型，可直接传递给 formatDate 函数
 * @enum {string}
 */
export const DATE_FORMAT_TYPE = {
  /** 完整日期时间格式，如: 2024-01-01 12:30:45 */
  DATETIME: 'datetime',
  /** 仅日期格式，如: 2024-01-01 */
  DATE_ONLY: 'date',
  /** 仅时间格式，如: 12:30:45 */
  TIME_ONLY: 'time',
  /** 短日期时间格式，如: 2024-01-01 12:30 */
  DATETIME_SHORT: 'datetime_short',
  /** 中文日期格式，如: 2024年01月01日 */
  DATE_CHINESE: 'date_chinese',
}

/**
 * 预定义的日期格式映射
 * 将格式类型常量映射到具体的格式化字符串
 * @private
 */
const FORMAT_MAP: Record<string, string> = {
  [DATE_FORMAT_TYPE.DATETIME]: 'YYYY-MM-DD HH:mm:ss',
  [DATE_FORMAT_TYPE.DATE_ONLY]: 'YYYY-MM-DD',
  [DATE_FORMAT_TYPE.TIME_ONLY]: 'HH:mm:ss',
  [DATE_FORMAT_TYPE.DATETIME_SHORT]: 'YYYY-MM-DD HH:mm',
  [DATE_FORMAT_TYPE.DATE_CHINESE]: 'YYYY年MM月DD日',
}

/**
 * 格式化相对时间
 * @param date 日期对象或日期字符串
 * @returns 格式化后的相对时间字符串
 */
export function formatRelativeTime(date: Date | string): string {
  const createTime = typeof date === 'string' ? new Date(date) : date
  const now = new Date()

  // 检查日期是否有效
  if (Number.isNaN(createTime.getTime())) {
    return '无效时间'
  }

  const diffMs = now.getTime() - createTime.getTime()
  const diffMinutes = Math.floor(diffMs / (1000 * 60))
  const diffHours = Math.floor(diffMs / (1000 * 60 * 60))
  const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))

  if (diffMinutes < 1) {
    return '刚刚'
  }
  else if (diffMinutes < 60) {
    return `${diffMinutes}分钟前`
  }
  else if (diffHours < 24) {
    return `${diffHours}小时前`
  }
  else if (diffDays < 30) {
    return `${diffDays}天前`
  }
  else {
    return createTime.toLocaleDateString()
  }
}

/**
 * 格式化日期
 * @param date 日期对象或日期字符串
 * @param formatOrType 格式化模板或预定义的格式类型
 * @returns 格式化后的日期字符串
 * @example
 * // 使用预定义格式类型
 * formatDate(new Date(), DATE_FORMAT_TYPE.DATE_ONLY) // '2024-01-01'
 * // 使用自定义格式
 * formatDate(new Date(), 'YYYY/MM/DD') // '2024/01/01'
 */
export function formatDate(
  date: Date | string,
  formatOrType: string = DATE_FORMAT_TYPE.DATETIME,
): string {
  const d = typeof date === 'string' ? new Date(date) : date

  // 检查日期是否有效
  if (Number.isNaN(d.getTime())) {
    return date.toString()
  }

  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  const hours = String(d.getHours()).padStart(2, '0')
  const minutes = String(d.getMinutes()).padStart(2, '0')
  const seconds = String(d.getSeconds()).padStart(2, '0')

  // 如果是预定义的格式类型，则使用对应的模板
  const formatTemplate = FORMAT_MAP[formatOrType] || formatOrType

  return formatTemplate
    .replace('YYYY', String(year))
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds)
}

/**
 * 将毫秒转换为人类可读的时间格式
 * @param milliseconds 毫秒数
 * @returns 格式化后的时间字符串，如 "1年2月3天4小时5分钟6秒"
 * @example
 * formatDuration(8777664) // "2小时26分钟17秒"
 * formatDuration(31536000000) // "1年"
 */
export function formatDuration(milliseconds: number): string {
  if (milliseconds < 0) {
    return '0秒'
  }

  // 定义时间单位（使用平均天数简化计算）
  const second = 1000
  const minute = second * 60
  const hour = minute * 60
  const day = hour * 24
  const month = day * 30
  const year = day * 365

  // 计算各个时间单位的值
  const years = Math.floor(milliseconds / year)
  const months = Math.floor((milliseconds % year) / month)
  const days = Math.floor((milliseconds % month) / day)
  const hours = Math.floor((milliseconds % day) / hour)
  const minutes = Math.floor((milliseconds % hour) / minute)
  const seconds = Math.floor((milliseconds % minute) / second)

  // 构建结果字符串
  const parts: string[] = []

  if (years > 0) {
    parts.push(`${years}年`)
  }
  if (months > 0) {
    parts.push(`${months}月`)
  }
  if (days > 0) {
    parts.push(`${days}天`)
  }
  if (hours > 0) {
    parts.push(`${hours}小时`)
  }
  if (minutes > 0) {
    parts.push(`${minutes}分钟`)
  }
  if (seconds > 0 || parts.length === 0) {
    parts.push(`${seconds}秒`)
  }

  return parts.join('')
}
